<template>
	<Teleport to="body">
		<transition name="loading-fade">
			<div v-if="show" class="loading-mask">
				<div class="loading-spinner" :class="themeClass">
					<div class="loading-circle-wrapper">
						<div class="loading-circle"></div>
						<div class="loading-circle-inner">
							<div class="loading-circle-pulse"></div>
						</div>
						<div v-if="showCountdown" class="countdown">{{ remaining }}s</div>
					</div>
					<div class="loading-text">
						<template v-if="theme === 'payment'"> <span>获</span><span>取</span><span>支</span><span>付</span><span>信</span><span>息</span> </template>
						<template v-else-if="theme === 'qrcode'"> <span>生</span><span>成</span><span>支</span><span>付</span><span>二</span><span>维</span><span>码</span> </template>
						<template v-else-if="theme === 'payment-result'"> <span>等</span><span>待</span><span>缴</span><span>费</span><span>结</span><span>果</span> </template>
						<template v-else-if="theme === 'invoice'"> <span>获</span><span>取</span><span>发</span><span>票</span><span>中</span> </template>
						<template v-else> <span>加</span><span>载</span><span>中</span> </template>
						<span class="dots"> <i></i><i></i><i></i> </span>
					</div>
				</div>
			</div>
		</transition>
	</Teleport>
</template>

<script setup>
	const props = defineProps({
		show: {
			type: Boolean,
			default: false,
		},
		duration: {
			type: Number,
			default: 30,
		},
		showCountdown: {
			type: Boolean,
			default: false,
		},
		theme: {
			type: String,
			default: 'qrcode',
			validator: (value) => ['default', 'payment', 'qrcode', 'payment-result', 'invoice'].includes(value),
		},
	});

	const emit = defineEmits(['update:show', 'timeout', 'timeRemaining', 'stop']);

	const countdown = ref(props.duration);

	const themeClass = computed(() => ({
		'theme-payment': props.theme === 'payment',
		'theme-qrcode': props.theme === 'qrcode',
		'theme-payment-result': props.theme === 'payment-result',
		'theme-invoice': props.theme === 'invoice',
	}));

	const { remaining, start, stop, pause, resume } = useCountdown(countdown.value, {
		controls: true, // 启用控制功能
		onComplete: () => {
			emit('update:show', false);
			emit('timeout', true);
		},
		onTick: () => {
			emit('timeRemaining', remaining.value);
		},
	});

	watch(
		() => props.show,
		(newVal) => {
			if (newVal && props.showCountdown) {
				stop();
				start();
				emit('stop', stop); // 将 stop 方法抛出给父组件
			} else {
				stop();
			}
		},
		{
			immediate: true, // 添加 immediate 选项，确保首次渲染时也会执行
			deep: true, // 添加 deep 选项，确保能够深度监听
		}
	);

	// 组件卸载
	onBeforeUnmount(() => {
		stop();
	});

	// 组件卸载
	onUnmounted(() => {
		stop();
	});

	defineExpose({
		stop,
	});
</script>

<style lang="scss" scoped>
	
	.loading-fade-enter-active,
	.loading-fade-leave-active {
		// transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
		transition: all 0.3s ease-in-out;
	}

	.loading-fade-enter-from,
	.loading-fade-leave-to {
		// transform: scale(0.95);
		opacity: 0;
	}
	.loading-mask {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background: rgba(0, 0, 0, 0.75);
		backdrop-filter: blur(4px);
		display: flex;
		justify-content: center;
		align-items: center;
		z-index: 9999;
	}

	.loading-spinner {
		padding: 50px 90px;
		background: rgba(255, 255, 255, 0.08);
		border-radius: 32px;
		box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
		backdrop-filter: blur(16px);
		border: 1px solid rgba(255, 255, 255, 0.15);
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.loading-circle-wrapper {
		position: relative;
		width: 100px;
		height: 100px;
		margin: 0 auto 25px;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	.loading-circle {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		border: 5px solid rgba(255, 255, 255, 0.15);
		border-top: 5px solid #ffffff;
		border-radius: 50%;
		animation: spin 1.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
		box-sizing: border-box;
	}

	.loading-circle-inner {
		position: absolute;
		top: 50%;
		left: 50%;
		width: 50%;
		height: 50%;
		background: rgba(255, 255, 255, 0.08);
		border-radius: 50%;
		transform: translate(-50%, -50%);
		box-shadow: 0 0 20px rgba(255, 255, 255, 0.15);
		overflow: hidden;
	}

	.loading-circle-pulse {
		position: absolute;
		top: 50%;
		left: 50%;
		width: 100%;
		height: 100%;
		background: radial-gradient(circle, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 70%);
		transform: translate(-50%, -50%);
		animation: pulse 2s ease-in-out infinite;
	}

	.countdown {
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		font-size: 20px;
		color: rgba(255, 255, 255, 0.95);
		font-weight: 600;
		letter-spacing: 1px;
		text-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
		font-family: 'SF Pro Display', 'Helvetica Neue', Arial, sans-serif;
	}

	.loading-text {
		font-size: 24px;
		color: #ffffff;
		font-weight: 500;
		letter-spacing: 6px;
		text-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
		margin-top: 10px;
	}

	.dots {
		display: inline-block;
		margin-left: 6px;
	}

	.dots i {
		display: inline-block;
		width: 6px;
		height: 6px;
		margin: 0 3px;
		background: #fff;
		border-radius: 50%;
		animation: dotScale 1.5s ease-in-out infinite;
	}

	.loading-text span {
		display: inline-block;
		opacity: 0.9;
		animation: fadeInOut 2s ease-in-out infinite;
	}

	.loading-text span:nth-child(2) {
		animation-delay: 0.2s;
	}

	.loading-text span:nth-child(3) {
		animation-delay: 0.4s;
	}

	.loading-text span:nth-child(4) {
		animation-delay: 0.6s;
	}

	.loading-text span:nth-child(5) {
		animation-delay: 0.8s;
	}

	.loading-text span:nth-child(6) {
		animation-delay: 1s;
	}

	@keyframes spin {
		0% {
			transform: rotate(0deg);
		}
		100% {
			transform: rotate(360deg);
		}
	}

	@keyframes fadeInOut {
		0%,
		100% {
			opacity: 0.3;
		}
		50% {
			opacity: 1;
		}
	}

	@keyframes dotScale {
		0%,
		100% {
			transform: scale(0.7);
			opacity: 0.3;
		}
		50% {
			transform: scale(1);
			opacity: 1;
		}
	}

	@keyframes pulse {
		0%,
		100% {
			transform: translate(-50%, -50%) scale(0.8);
			opacity: 0.5;
		}
		50% {
			transform: translate(-50%, -50%) scale(1.2);
			opacity: 0.8;
		}
	}

	/* 主题样式 */
	.theme-payment {
		background: rgba(82, 196, 26, 0.08);
		border-color: rgba(82, 196, 26, 0.15);
	}

	.theme-payment .loading-circle {
		border-top-color: #52c41a;
	}

	.theme-payment .loading-circle-inner {
		background: rgba(82, 196, 26, 0.08);
		box-shadow: 0 0 20px rgba(82, 196, 26, 0.15);
	}

	.theme-qrcode {
		background: rgba(24, 144, 255, 0.08);
		border-color: rgba(24, 144, 255, 0.15);
	}

	.theme-qrcode .loading-circle {
		border-top-color: #1890ff;
	}

	.theme-qrcode .loading-circle-inner {
		background: rgba(24, 144, 255, 0.08);
		box-shadow: 0 0 20px rgba(24, 144, 255, 0.15);
	}

	.theme-payment-result {
		background: rgba(250, 140, 22, 0.08);
		border-color: rgba(250, 140, 22, 0.15);
	}

	.theme-payment-result .loading-circle {
		border-top-color: #fa8c16;
	}

	.theme-payment-result .loading-circle-inner {
		background: rgba(250, 140, 22, 0.08);
		box-shadow: 0 0 20px rgba(250, 140, 22, 0.15);
	}

	.theme-invoice {
		background: rgba(103, 58, 183, 0.08);
		border-color: rgba(103, 58, 183, 0.15);
	}

	.theme-invoice .loading-circle {
		border-top-color: #673ab7;
	}

	.theme-invoice .loading-circle-inner {
		background: rgba(103, 58, 183, 0.08);
		box-shadow: 0 0 20px rgba(103, 58, 183, 0.15);
	}
</style>
